package com.jeeplus.test.jlnu.student.service.impl;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.excel.util.DateUtils;
import com.alibaba.excel.util.StringUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jeeplus.file.config.FileProperties;
import com.jeeplus.file.repository.AccessoryRepository;
import com.jeeplus.security.util.SecurityUtils;
import com.jeeplus.test.jlnu.admissionInfo.mapper.AdmissionInfoMapper;
import com.jeeplus.test.jlnu.changeStuInfo.domain.entity.ChangeStuInfo;
import com.jeeplus.test.jlnu.changeStuInfo.domain.entity.ChangeStuInfoHistory;
import com.jeeplus.test.jlnu.changeStuInfo.mapper.ChangeAuditMapper;
import com.jeeplus.test.jlnu.changeStuInfo.mapper.ChangeStuInfoMapper;
import com.jeeplus.test.jlnu.student.domain.entity.BsssStudentInfo;
import com.jeeplus.test.jlnu.student.domain.entity.StudentField;
import com.jeeplus.test.jlnu.student.domain.entity.StudentInfoApprove;
import com.jeeplus.test.jlnu.student.domain.result.NameAndPassword;
import com.jeeplus.test.jlnu.student.domain.vo.BsssStudentInfoReqVo;
import com.jeeplus.test.jlnu.student.dto.VerifyResponse;
import com.jeeplus.test.jlnu.student.mapper.BsssStudentInfoMapper;
import com.jeeplus.test.jlnu.student.mapper.StudentInfoApproveMapper;
import com.jeeplus.test.jlnu.student.service.BsssStudentInfoService;
import com.jeeplus.test.tools.resp.R;
import com.jeeplus.test.website.websiteFile.domain.entity.WebsiteFile;
import com.jeeplus.test.website.websiteFile.service.WebsiteFileService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;


import java.text.ParseException;
import java.text.SimpleDateFormat;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class BsssStudentInfoServiceImpl extends ServiceImpl<BsssStudentInfoMapper, BsssStudentInfo> implements BsssStudentInfoService {
    @Autowired
    private BsssStudentInfoMapper bsssStudentInfoMapper;

    @Autowired
    private AdmissionInfoMapper admissionInfoMapper;

    @Autowired
    private ChangeAuditMapper changeAuditMapper;

    @Autowired
    private FileProperties fileProperties;


    @Autowired
    StudentInfoApproveMapper studentInfoApproveMapper;

    @Autowired
    private WebsiteFileService websiteFileService;

    @Autowired
    private ChangeStuInfoMapper changeStuInfoMapper;

    private String FILE_SERVER = "/file";

    @Value("${config.accessory.minIO.endpoint}")
    private String systemMac;

    @Autowired
    private AccessoryRepository accessoryRepository;

    @Override
    public BsssStudentInfo getBsssStudentInfo(String studentId, String flag) {
        LambdaQueryChainWrapper<BsssStudentInfo> wrapper = new LambdaQueryChainWrapper<>(bsssStudentInfoMapper);

        BsssStudentInfo bsssStudentInfo = bsssStudentInfoMapper.selectStudent(studentId, flag);

//        wrapper.eq(BsssStudentInfo::getStudentId, studentId);
//        wrapper.eq(BsssStudentInfo::getFlag, flag);
        return bsssStudentInfo;
    }

    @Override
    public Boolean bsssStudentInfoUpdate(BsssStudentInfo bsssStudentInfo) {
        LambdaUpdateChainWrapper<BsssStudentInfo> wrapper = new LambdaUpdateChainWrapper<>(bsssStudentInfoMapper);
        String id = bsssStudentInfo.getStudentId();
        if (ObjectUtil.isNotEmpty(bsssStudentInfo.getAge())) {
            wrapper.set(BsssStudentInfo::getAge, bsssStudentInfo.getAge());
            admissionInfoMapper.updateAge(bsssStudentInfo.getAge(),id);
        }
        if (ObjectUtil.isNotEmpty(bsssStudentInfo.getContactNumber())) {
            wrapper.set(BsssStudentInfo::getContactNumber, bsssStudentInfo.getContactNumber());
            admissionInfoMapper.updatePhoneNum(bsssStudentInfo.getContactNumber(),id);
            //手机号
        }
        //个人校内信息修改
        if (ObjectUtil.isNotEmpty(bsssStudentInfo.getWechatId())) {
            wrapper.set(BsssStudentInfo::getWechatId, bsssStudentInfo.getWechatId());
        }
        if (ObjectUtil.isNotEmpty(bsssStudentInfo.getSpecialties())) {
            wrapper.set(BsssStudentInfo::getSpecialties, bsssStudentInfo.getSpecialties());
        }
        if (ObjectUtil.isNotEmpty(bsssStudentInfo.getQqId())) {
            wrapper.set(BsssStudentInfo::getQqId, bsssStudentInfo.getQqId());
        }
        if (ObjectUtil.isNotEmpty(bsssStudentInfo.getEmail())) {
            wrapper.set(BsssStudentInfo::getEmail, bsssStudentInfo.getEmail());
        }
        if (ObjectUtil.isNotEmpty(bsssStudentInfo.getSpecialties())) {
            wrapper.set(BsssStudentInfo::getSpecialties, bsssStudentInfo.getSpecialties());
        }
        if (ObjectUtil.isNotEmpty(bsssStudentInfo.getInterests())) {
            wrapper.set(BsssStudentInfo::getInterests, bsssStudentInfo.getInterests());
        }
        if (ObjectUtil.isNotEmpty(bsssStudentInfo.getHealthStatus())) {
            wrapper.set(BsssStudentInfo::getHealthStatus, bsssStudentInfo.getHealthStatus());
        }
        if (ObjectUtil.isNotEmpty(bsssStudentInfo.getHeight())) {
            wrapper.set(BsssStudentInfo::getHeight, bsssStudentInfo.getHeight());
        }
        if (ObjectUtil.isNotEmpty(bsssStudentInfo.getMaritalStatus())) {
            wrapper.set(BsssStudentInfo::getMaritalStatus, bsssStudentInfo.getMaritalStatus());
        }
//        if (ObjectUtil.isNotEmpty(bsssStudentInfo.getPostalCode())) {
//            wrapper.set(BsssStudentInfo::getPostalCode, bsssStudentInfo.getPostalCode());
//            admissionInfoMapper.updatePostalCode(bsssStudentInfo.getPostalCode(),id);
//        }
        //个人生源信息修改
        if (ObjectUtil.isNotEmpty(bsssStudentInfo.getPoliticalAffiliation())) {
            wrapper.set(BsssStudentInfo::getPoliticalAffiliation, bsssStudentInfo.getPoliticalAffiliation());
        }
        if (ObjectUtil.isNotEmpty(bsssStudentInfo.getBirthplace())) {
            wrapper.set(BsssStudentInfo::getBirthplace, bsssStudentInfo.getBirthplace());
        }

        if (ObjectUtil.isNotEmpty(bsssStudentInfo.getApplySchools())) {
            wrapper.set(BsssStudentInfo::getApplySchools, bsssStudentInfo.getApplySchools());
        }

        if (ObjectUtil.isNotEmpty(bsssStudentInfo.getAddressee())) {
            wrapper.set(BsssStudentInfo::getAddressee, bsssStudentInfo.getAddressee());
        }

        if (ObjectUtil.isNotEmpty(bsssStudentInfo.getAdmissionLetterAddress())) {
            wrapper.set(BsssStudentInfo::getAdmissionLetterAddress, bsssStudentInfo.getAdmissionLetterAddress());
        }

        if (ObjectUtil.isNotEmpty(bsssStudentInfo.getFamilyDetailedAddress())) {
            wrapper.set(BsssStudentInfo::getFamilyDetailedAddress, bsssStudentInfo.getFamilyDetailedAddress());
        }

        if (ObjectUtil.isNotEmpty(bsssStudentInfo.getPreviousWorkUnitAddress())) {
            wrapper.set(BsssStudentInfo::getPreviousWorkUnitAddress, bsssStudentInfo.getPreviousWorkUnitAddress());
        }

        //根据id修改
        wrapper.eq(BsssStudentInfo::getId, bsssStudentInfo.getId());

        //查询基本信息审查表中是否存在修改表
        // 改用查询条件构造器
        LambdaQueryChainWrapper<StudentInfoApprove> queryWrapper =
                new LambdaQueryChainWrapper<>(studentInfoApproveMapper);

        // 查询是否存在记录
        Optional<StudentInfoApprove> info = queryWrapper
                .eq(StudentInfoApprove::getStudentId, bsssStudentInfo.getStudentId())
                .eq(StudentInfoApprove::getOutsideType, "1")
                .eq(StudentInfoApprove::getFlag, bsssStudentInfo.getFlag())
                .oneOpt();

        // 生成 VerifyResponse 的 JSON 数据
        String data = generateVerifyResponseJson(bsssStudentInfo);

        // 根据查询结果执行更新或插入
        if (info.isPresent()) {
            // 更新操作
            StudentInfoApprove studentInfoApprove = new StudentInfoApprove();
            studentInfoApprove.setContent(data);
            studentInfoApprove.setStudentId(bsssStudentInfo.getStudentId());
            studentInfoApprove.setOutsideType("1");
            studentInfoApprove.setApprovalStatus(0);
            studentInfoApprove.setName(bsssStudentInfo.getName());
            studentInfoApprove.setIdCardNumber(bsssStudentInfo.getIdCardNumber());
            studentInfoApprove.setFlag(bsssStudentInfo.getFlag());
            studentInfoApproveMapper.updateStudentInfoApprove(studentInfoApprove);
            //修改时需要将 家庭详细地址同步给 outsideType为2和3的
            {
                for (String outsideType : Arrays.asList("2", "3")) {
                    //查询是否存在记录
                    Optional<StudentInfoApprove> query = new LambdaQueryChainWrapper<>(studentInfoApproveMapper)
                            .eq(StudentInfoApprove::getStudentId, bsssStudentInfo.getStudentId())
                            .eq(StudentInfoApprove::getOutsideType, outsideType)
                            .eq(StudentInfoApprove::getFlag, bsssStudentInfo.getFlag())
                            .oneOpt();
                    if(query.isPresent()){
                        StudentInfoApprove studentInfoApproveByOutsideType = query.get();
                        String content = studentInfoApproveByOutsideType.getContent();
                        JSONObject jsonObject = JSON.parseObject(content);
                        jsonObject.put("familyDetailedAddress",bsssStudentInfo.getFamilyDetailedAddress());
                        studentInfoApproveMapper.updateStudentInfoApproveContent(studentInfoApproveByOutsideType.getStudentId(), outsideType, JSON.toJSONString(jsonObject));
                    }
                }
            }
        } else {
            // 插入操作
            StudentInfoApprove studentInfoApprove = createNewStudentInfoApprove(data,bsssStudentInfo);
            studentInfoApprove.setOutsideType("1");
            studentInfoApprove.setApprovalStatus(0);
            studentInfoApproveMapper.insertStudentInfoApprove(studentInfoApprove);
        }
        return wrapper.update();
    }

    @Override
    public R imgUpload(MultipartFile file,String studentId,String type) {
        Calendar cal = Calendar.getInstance();
        Map<String, String> resultMap = new HashMap<>();

        int year = cal.get(Calendar.YEAR);
        int month = cal.get(Calendar.MONTH) + 1;

        String uploadPath = "/file/test" + "/" + year + "/" + month + "/";
        String minioPath = "/test" + "/" + year + "/" + month + "/";

        // 判断文件是否为空
        if (!file.isEmpty()) {
            String name = file.getOriginalFilename();
            if (fileProperties.isAvailable(name)) {
                // 文件保存
                //accessoryRepository.save(file, uploadPath, name);
                accessoryRepository.save(file, minioPath, name);

                // 生成唯一 ID
                String fileId = IdUtil.simpleUUID();

                // 生成 URL
                String fileUrl = systemMac  + FILE_SERVER + minioPath + name;

                // 保存到数据库
                WebsiteFile websiteFile = new WebsiteFile();
                websiteFile.setId(fileId);
                websiteFile.setFileUrl(fileUrl);
                websiteFile.setFileName(name);
                websiteFile.setBucketName(uploadPath);
                websiteFile.setBucketId(FILE_SERVER);
                websiteFile.setCreateTime(new Date());
                websiteFileService.save(websiteFile);
                BsssStudentInfo bsssStudentInfo = new BsssStudentInfo();
                if(type != null && type.equals("signature")){
                    bsssStudentInfo.setStudentId(studentId).setSignature(fileUrl);
                }else {
                    bsssStudentInfo.setStudentId(studentId).setStudentUrl(fileUrl);
                }
                bsssStudentInfoMapper.updateByStudentId(bsssStudentInfo);
                // 将 ID 和 URL 放入 Map
                resultMap.put("id", fileId);
                resultMap.put("url", fileUrl);
                return R.suc(resultMap);
            } else {
                return R.error("9999","上传失败");
            }
        } else {
            return R.error("9999","上传失败");
        }


    }


    @Override
    public NameAndPassword check(String studentId, String idCard) {

        BsssStudentInfo bsssStudentInfo = new LambdaQueryChainWrapper<>(bsssStudentInfoMapper)
                .eq(BsssStudentInfo::getStudentId, studentId)
                .one();
        if (bsssStudentInfo == null) {
            throw new RuntimeException("学生不存在");
        }
        if(bsssStudentInfo.getIdCardNumber() == null){
        throw new RuntimeException("身份证号不存在");
        }
        if(bsssStudentInfo.getPassword() == null){
            String lastSixDigits = bsssStudentInfo.getIdCardNumber().substring(bsssStudentInfo.getIdCardNumber().length() - 6);
            if(!idCard.equals(lastSixDigits)){
                throw new RuntimeException("身份证号错误");
            }
            return new NameAndPassword().setStudentId(studentId).setIdCard(bsssStudentInfo.getIdCardNumber()).setFlag(bsssStudentInfo.getFlag());

        }else {
            if(!SecurityUtils.validatePassword(idCard,bsssStudentInfo.getPassword())){
                throw new RuntimeException("密码错误");
            }
        }
        NameAndPassword nameAndPassword = new NameAndPassword().setStudentId(studentId).setFlag(bsssStudentInfo.getFlag());
        //前端显示菜单用是否毕业标识
        ChangeStuInfo changeStuInfo = changeStuInfoMapper.getByStudentId(studentId);
        try {
            nameAndPassword.setGraduationBadge(
                    changeStuInfo == null ||
                    StringUtils.isEmpty(changeStuInfo.getGraduationTime()) ||
                    DateUtils.parseDate(changeStuInfo.getGraduationTime()).before(new Date())
            );
        } catch (ParseException e) {
            nameAndPassword.setGraduationBadge(true);
        }
        return nameAndPassword;

    }

    @Override
    public List<ChangeStuInfoHistory.GroupedChangeHistory> groupingByInfoId(Long infoId) {
        List<ChangeStuInfoHistory> rawList = changeAuditMapper.groupingByInfoId(infoId);

        // 2. 调用分组方法
        return groupByChangeDate(rawList);
    }

    @Override
    public Page<BsssStudentInfo> selectStudentInfoListPage(BsssStudentInfo bsssStudentInfo, Page<BsssStudentInfo> page) {
        Page<BsssStudentInfo> studentInfoListPage = bsssStudentInfoMapper.selectStudentInfoList(bsssStudentInfo, page);
        return studentInfoListPage;
    }

    @Override
    public int changePassword(BsssStudentInfo bsssStudentInfo) {
        bsssStudentInfo.setPassword ( SecurityUtils.encryptPassword (bsssStudentInfo.getPassword()));
        return bsssStudentInfoMapper.updateByStudentId(bsssStudentInfo);
    }

    @Override
    public void addStudentInfoApprove(BsssStudentInfo bsssStudentInfo) {
        LambdaQueryChainWrapper<StudentInfoApprove> queryWrapper =
                new LambdaQueryChainWrapper<>(studentInfoApproveMapper);
        // 查询是否存在记录
        Optional<StudentInfoApprove> info = queryWrapper
                .eq(StudentInfoApprove::getStudentId, bsssStudentInfo.getStudentId())
                .eq(StudentInfoApprove::getOutsideType, "3")
                .eq(StudentInfoApprove::getFlag, bsssStudentInfo.getFlag())
                .oneOpt();

        // 生成 VerifyResponse 的 JSON 数据
        String data = generateVerifyResponseJson(bsssStudentInfo);

        // 根据查询结果执行更新或插入
        if (info.isPresent()) {
            // 更新操作
            StudentInfoApprove studentInfoApprove = new StudentInfoApprove();
            studentInfoApprove.setContent(data);
            studentInfoApprove.setStudentId(bsssStudentInfo.getStudentId());
            studentInfoApprove.setOutsideType("3");
            studentInfoApprove.setApprovalStatus(0);
            studentInfoApprove.setName(bsssStudentInfo.getName());
            studentInfoApprove.setIdCardNumber(bsssStudentInfo.getIdCardNumber());
            studentInfoApprove.setFlag(bsssStudentInfo.getFlag());
            bsssStudentInfoMapper.updateBirthDateByStudentId(bsssStudentInfo);
            studentInfoApproveMapper.updateStudentInfoApprove(studentInfoApprove);
        } else {
            // 插入操作
            StudentInfoApprove studentInfoApprove = createNewStudentInfoApprove(data,bsssStudentInfo);
            studentInfoApprove.setOutsideType("3");
            studentInfoApprove.setApprovalStatus(0);
            studentInfoApproveMapper.insertStudentInfoApprove(studentInfoApprove);
        }
    }
    @Override
    public Page<BsssStudentInfo> getBsssStudentInfoPage(BsssStudentInfoReqVo bsssStudentInfoReqVo, Page<BsssStudentInfo> page) {
        return bsssStudentInfoMapper.getBsssStudentInfoPage(bsssStudentInfoReqVo,page);
    }

    @Override
    public BsssStudentInfo getStudentByStudentId(BsssStudentInfoReqVo bsssStudentInfoReqVo) {
        return bsssStudentInfoMapper.getStudentByStudentId(bsssStudentInfoReqVo);
    }

    @Override
    public Page<StudentField> getStudentInfoPage(StudentField studentField, Page<StudentField> page) {
        // 参数校验增强
        if(studentField == null || StringUtils.isEmpty(studentField.getFlag())) {
            throw new IllegalArgumentException("参数不能为空");
        }

        //验证type有效性
        if(!Arrays.asList(1, 2, 3, 4, 5, 6).contains(studentField.getType())) {
            throw new IllegalArgumentException("无效的类型参数");
        }

        return bsssStudentInfoMapper.getStudentInfoPage(studentField, page);
    }

    @Override
    public StudentField getStudentData(StudentField studentField) {
        // 参数校验增强
        if(studentField == null || StringUtils.isEmpty(studentField.getFlag())|| StringUtils.isEmpty(studentField.getStudentId())) {
            throw new IllegalArgumentException("参数不能为空");
        }

        // 验证type有效性
        if(!Arrays.asList(1, 2, 3, 4, 5, 6).contains(studentField.getType())) {
            throw new IllegalArgumentException("无效的类型参数");
        }

        return bsssStudentInfoMapper.getStudentData(studentField);
    }






//    @Override
//    public ResponseEntity<byte[]> generatePdf(String studentId) {
//        // 1. 加载模板文件
//        ClassPathResource template = new ClassPathResource("static/基本信息核查表.pdf");
//
//        // 2. 转换DTO为字段映射表
//        Map<String, String> fieldMap = new HashMap<>();
////        fieldMap.put("studentName", "2222");
//
//        try (InputStream inputStream = template.getInputStream()) {
//            byte[] pdfBytes = PdfTemplateFiller.fillTemplate(inputStream, fieldMap);
//            Path outputPath = Paths.get("debug_output.pdf");
//            System.out.println("文件路径: " + outputPath.toAbsolutePath());
//            Files.write(Paths.get("debug_output.pdf"), pdfBytes);
//            return ResponseEntity.ok()
//                    .header(HttpHeaders.CONTENT_DISPOSITION, "inline; filename=document.pdf")
//                    .contentType(MediaType.APPLICATION_PDF)
//                    .body(pdfBytes);
//        } catch (IOException e) {
//            throw new RuntimeException("PDF生成失败", e);
//        }
//
//    }


    // 分组逻辑
    public List<ChangeStuInfoHistory.GroupedChangeHistory> groupByChangeDate(List<ChangeStuInfoHistory> list) {
        return list.stream()
                .collect(Collectors.groupingBy(
                        ChangeStuInfoHistory::getChangeDate,
                        LinkedHashMap::new,  // 保持顺序
                        Collectors.toList()
                ))
                .entrySet().stream()
                .map(entry -> new ChangeStuInfoHistory.GroupedChangeHistory()
                        .setChangeDate(entry.getKey())
                        .setItems(entry.getValue())
                )
                .collect(Collectors.toList());
    }


    // 生成 VerifyResponse 的 JSON 数据
    private String generateVerifyResponseJson(BsssStudentInfo bsssStudentInfo) {
        try {
            // 日期格式化

            VerifyResponse verifyResponse = new VerifyResponse();

            if(bsssStudentInfo.getBirthDate() != null){
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                String birthDateStr = sdf.format(bsssStudentInfo.getBirthDate());
                verifyResponse.setBirthDate(birthDateStr);
            }
            BeanUtils.copyProperties(bsssStudentInfo, verifyResponse);
            // JSON 序列化
            ObjectMapper mapper = new ObjectMapper();
            return mapper.writeValueAsString(verifyResponse);
        } catch (JsonProcessingException e) {
            throw new RuntimeException("JSON 序列化失败", e);
        }
    }

    // 创建新记录对象
    private StudentInfoApprove createNewStudentInfoApprove(String data,BsssStudentInfo bsssStudentInfo) {
        StudentInfoApprove studentInfoApprove = new StudentInfoApprove();
        studentInfoApprove.setStudentId(bsssStudentInfo.getStudentId());
        studentInfoApprove.setContent(data);
        studentInfoApprove.setOfficeId(bsssStudentInfo.getOfficeId());
        studentInfoApprove.setFlag(bsssStudentInfo.getFlag());
        studentInfoApprove.setApprovalStatus(0);
        return studentInfoApprove;
    }

    @Override
    public BsssStudentInfo studentForgotPasswordCheck(BsssStudentInfoReqVo bsssStudentInfoReqVo) {
        return bsssStudentInfoMapper.studentForgotPasswordCheck(bsssStudentInfoReqVo);
    }
}
